<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Role;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use App\Http\Resources\UserResource;
use Carbon\Carbon;
use Illuminate\Support\Facades\Mail;
use App\Mail\RegisterConfirmationEmail;
use Illuminate\Support\Facades\App;

class AuthController
{
  public function register(Request $request)
  {
    Log::debug(__METHOD__);

    $response = $newuser = [];
    $httpcode = 201;
    $validator = $user = null;

    $newuser = $request->all();
    $role = Role::where('slug', config('coreapi.registered_user_role'))->first();
    $newuser['role_id'] = $role->id;
    $validator = Validator::make($newuser, User::$insertRules);
    if ($validator->fails()) {
      $response = ['error' => $validator->errors()];
      $httpcode = 400;
    } else {
      $newuser['registered'] = true;
      if (config('coreapi.registered_user_confirmation_email')) {
        Mail::to($newuser['email'])->send(new RegisterConfirmationEmail($newuser, App::getLocale()));
        $newuser['active'] = false;
      } else {
        $newuser['active'] = true;
      }
      $user = User::create($newuser);
      $resource = new UserResource($user);
      $response = [
        'user' => $resource,
        'message' => trans('coreapi.register_ok')
      ];
    }

    return response()->json($response, $httpcode);
  }

  public function login(Request $request)
  {
    Log::debug(__METHOD__);

    $response = [];
    $httpcode = 200;
    $token = '';
    $validator = $user = null;

    $validator = Validator::make($request->all(), User::$loginRules);
    if ($validator->fails()) {
      $response = ['error' => $validator->errors()];
      $httpcode = 400;
    } else {
      $user = User::where([
        'email' => $request->email,
      ])->first();
      if ($user) {
        if (Hash::check($request->password, $user->password)) {
          $token = $user->createToken(env('APP_NAME'))->plainTextToken;
          $response = ['coreapi_token' => $token];
          $response['message'] = trans('coreapi.log_in_ok');
          $this->updUserTimestamp($user->id, 'last_login_at');
        } else {
          $response = ['message' => trans('coreapi.bad_credentials')];
          $httpcode = 401;
        }
      } else {
        $response = ['message' => trans('coreapi.email_not_found')];
        $httpcode = 401;
      }
    }
    return response()->json($response, $httpcode);
  }

  public function logout(Request $request)
  {
    Log::debug(__METHOD__);

    $response = ['message' => trans('coreapi.log_out_ok')];
    $httpcode = 200;
    $user = $request->user();

    if (isset($user)) {
      $user->currentAccessToken()->delete();
      $this->updUserTimestamp($user->id, 'last_logout_at');
    } else {
      $response = ['message' => trans('coreapi.logged_user_ko')];
      $httpcode = 401;
    }
    return response()->json($response, $httpcode);
  }

  public function activate(Request $request)
  {
    Log::debug(__METHOD__);

    $user = $view = null;

    App::setLocale($request->locale);
    $user = User::where([
      'email' => $request->email,
      'active' => false,
    ])->first();
    if ($user) {
      $user->update([
        'active' => true,
        'email_verified_at' => Carbon::now(),
      ]);
      $view = view('activate_ok');
    } else {
      $view = view('activate_ko');
    }

    return $view;
  }

  public function authenticatedUser(Request $request)
  {
    Log::debug(__METHOD__);

    $user = $request->user();
    $resource = new UserResource($user);

    return response()->json(['user' => $resource], 200);
  }

  private function updUserTimestamp(int $id, string $column)
  {
    Log::debug(__METHOD__);

    $userToUpd = null;

    $userToUpd = User::where('id', $id);
    $userToUpd->update([$column => Carbon::now()]);
  }
}
